package cn.wzy.listener;

import cn.wzy.annotation.AnPermission;
import cn.wzy.mapper.PermissionMapper;
import cn.wzy.pojo.Permission;
import cn.wzy.utils.ClassUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.context.support.WebApplicationContextUtils;

import javax.annotation.Resource;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Objects;

@WebListener
public class PermissionListener implements ServletContextListener {
    @Value("${anpermission.scan.path}")
    private String scanPath;
    @Resource
    private PermissionMapper permissionMapper;

    @Override
    @Transactional
    public void contextInitialized(ServletContextEvent sce) {
        WebApplicationContextUtils.getRequiredWebApplicationContext(sce.getServletContext())
                .getAutowireCapableBeanFactory().autowireBean(this);
//        获取到Controller包下所有controller
        List<Class> allClassName = ClassUtils.getAllClassName(scanPath);
//        寻找到有权限注解的controller
        for (Class aClass : allClassName) {
            AnPermission annotation = (AnPermission) aClass.getAnnotation(AnPermission.class);
//            如果没有注解，跳过
            if (Objects.isNull(annotation)){
                continue;
            }
//            获取到注解Controller中对应的Permission的属性
            Permission parent = new Permission();
            parent.setName(annotation.name());
            parent.setDescs(annotation.descs());
//            获取url
            RequestMapping mappingAnnotation = (RequestMapping)aClass.getAnnotation(RequestMapping.class);
            String parentUrl = mappingAnnotation.value()[0];
//            parent.setUrl(parentUrl);
//            获取sn
            parent.setSn(aClass.getSimpleName());
//            判断数据库中是否有该权限.通过sn
            Permission permissionSn = permissionMapper.getPermissionBySn(parent.getSn());
            if (Objects.isNull(permissionSn)){
                //            将父权限放入数据库中
                permissionMapper.addPermission(parent);
                System.out.println(parent.getId());
            }else {
//                修改
                permissionSn.setUrl(parent.getUrl());
                permissionSn.setName(parent.getName());
                permissionSn.setDescs(parent.getDescs());
                permissionSn.setSn(parent.getSn());
                permissionMapper.updatePermission(permissionSn);

            }

//            寻找到注解Controller中的注解方法
            Method[] methods = aClass.getMethods();
            for (Method method : methods) {
//                如果没有注解，跳过
                AnPermission methodAnnotation = method.getAnnotation(AnPermission.class);
                if (Objects.isNull(methodAnnotation)){
                    continue;
                }
//                获取到Controller中注解方法对应的Permission的属性
                Permission permission = new Permission();
                permission.setName(methodAnnotation.name());
                permission.setDescs(methodAnnotation.descs());
//                获取到url
                String url = ClassUtils.methodUrl(method, parentUrl);
                permission.setUrl(url);
//                获取到sn
                permission.setSn(aClass.getSimpleName()+":"+method.getName());
//                获取到父id
                permission.setParent_id(parent.getId());
//                放入数据库中
//                判断数据库中是否有该权限.通过sn
                Permission permissionMethodSn = permissionMapper.getPermissionBySn(permission.getSn());
                if (Objects.isNull(permissionMethodSn)){
//                    添加到数据库
                    permissionMapper.addPermission(permission);
                }else {
                    permissionMethodSn.setSn(permission.getSn());
                    permissionMethodSn.setName(permission.getName());
                    permissionMethodSn.setUrl(permission.getUrl());
                    permissionMethodSn.setParent_id(permissionSn.getId());
//                    修改数据库
                    permissionMapper.updatePermission(permissionMethodSn);
                }

            }
        }
    }
}
